import { readonly, ref } from 'vue'

function getDefaultValue (
  storage = localStorage,
  key = '',
  defaultValue?: unknown,
  errorHandler = (e: any) => console.error(e)
) {
  if (defaultValue) {
    return defaultValue
  }
  const val = storage.getItem(key)
  // 防止字符串格式化后导致的“”问题
  if (val && val !== '""') {
    try {
      return JSON.parse(val)
    } catch (e) {
      errorHandler('useStorage:' + e)
    }
  }
  return undefined
}
/**
 * @description 操作数据存储的store
 * @param {String} key 入库的key
 * @param {*} val 需要存储的内容，不传为获取值
 * @param {sessionStorage, localStorage} storage 使用的存储库，可选择sessionStorage, localStorage，默认为localStorage
 * @returns state: 只读的值
 * @returns setState: 用于修改storage,不传则为clear
 * @author jinzz
 * @FIXME: 未来需要增加对paina库的兼容处理，以及cookie、mongodb的处理，目前类型还太少
 * @FIXME: 未来需要增加对传递进来的数据，进行分类处理，分类规则如下：
 *  1. 如果是复杂类型则存储格式化后的数据
 *  2. 如果是简单类型则直接存储
 *  3. 如果传入存储规则，则按照存储规则进行存储
 */
export function useStorage (
  key: string,
  val?: unknown,
  storage = localStorage
) {
  const value = getDefaultValue(storage, key, val)
  const state = ref()
  const setState = (val: string | undefined) => {
    if (val === undefined) {
      storage.removeItem(key)
      state.value = null
    } else {
      storage.setItem(key, JSON.stringify(val))
      state.value = val
    }
  }
  setState(value)
  return {
    state: readonly(state),
    setState
  }
}